/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.uoc.tfc.exuoc.vistes;

import edu.uoc.tfc.exuoc.config.Config;
import edu.uoc.tfc.exuoc.controladors.AbstractInGestor;
import edu.uoc.tfc.exuoc.controladors.GestorItems;
import edu.uoc.tfc.exuoc.controladors.GestorContenidors;
import edu.uoc.tfc.exuoc.errors.AfegirDAOException;
import edu.uoc.tfc.exuoc.errors.ModDAOException;
import edu.uoc.tfc.exuoc.errors.EliDAOException;
import edu.uoc.tfc.exuoc.errors.BuitException;
import edu.uoc.tfc.exuoc.errors.LlistatDAOException;
import edu.uoc.tfc.exuoc.errors.LlegirDAOException;
import edu.uoc.tfc.exuoc.utils.seguretat.InjeccioCodi;

import edu.uoc.tfc.exuoc.model.Item;

import edu.uoc.tfc.exuoc.model.Contenidor;

import edu.uoc.tfc.exuoc.consultes.ContenidorLlistat;
import edu.uoc.tfc.exuoc.consultes.ItemLlistat;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.hibernate.HibernateException;


/**
 *
 * @author emoreno
 */
public class IGestorContenidors  extends AbstractInGestor
            implements  ModelDriven<Contenidor>{
        


        //Entitat gestionada
    private Contenidor contenidor=null;
    private Long idContenidorActual=Config.valorNull;

    //Classe Gestora
    private  GestorContenidors gcI =null;
       

    private int contenidorsPerPagina=Config.CONTENIDOR_PAGE*2-2;
    private int itemsPerPagina=Config.ITEM_PAGE+2;

    private List<ItemLlistat>       llistaIt = new ArrayList<ItemLlistat>();
    private List<ContenidorLlistat> llistaCon = new ArrayList<ContenidorLlistat>();
    private int nContenidors=0;
    private int nItems=0;
    private int pos=0;

    //Identificador de sessió
   //Emili_30-12-2011:No es fa servir ?: private String idSessio="";


   /* public IGestorContenidors(){
       //Emili:30-12-2011:Cal ?: this.openGestor();
        }
*/
     @Override
    public Contenidor getModel() {
        return contenidor;
    }


    @Override
    public void prepare() {
        //Emili:30-12-2011:Contenidor c=null;

        //Actualitzem la data de la sessió per l'usuari i assignem a idSessio
        //la sessió que li correspon.
        super.prepare();
        //03-12-:2012:if (gcI!=null ) this.closeGestor();
        this.openGestor();
        
        this.getLog().info("IGC:prepare: id="+idContenidorActual);

        try {
            if (this.idContenidorActual.equals(Config.valorNull) ||
                this.idContenidorActual.equals(null)){
                contenidor= new Contenidor();
            }else{
                try {

                // GestorContenidors gc = new GestorContenidors();
                //Emili:30-12-2011:canvait: c =gcI.llegirContenidor(idContenidorActual);
                //Emili:03-01-2012:contenidor=gcI.llegirContenidor(idContenidorActual);
                
                    contenidor=GestorContenidors.getInstance()
                                        .llegir(idContenidorActual);
                    if (contenidor==null){
                        this.getLog().error("Prepare: Cotenidor no trobat id: "
                            +this.idContenidorActual);
                        contenidor=new Contenidor();
                    }
                    else {
                        // si no s'ha trobat el contenidor es guarda un avís
                        this.getLog().info("prepare:  c="+contenidor.toString());
                        //this.setContenidor(c);
                        //gc.tancar();
                        // this.getLog().info("------------------------------,"+this.getModel());

                        //Emili:31-12-2011: c=null;
                        // this.closeGestor();
                        //this.getLog().info("------------------------------,"+this.getModel());
                    }
                }catch (LlegirDAOException e){
                    if (this.getIdContenidorActual()!=null)
                    this.getLog().error("IGC:prepare:Algun valor null, Actual :"
                        +this.getIdContenidorActual());
                    if (this.contenidor!=null)
                    this.getLog().error("IGC:prepare:Algun valor null, contenidor :"
                        +contenidor.toString());
                }
                 
            }

        }catch (NullPointerException e){
            if (this.getIdContenidorActual()!=null) 
                this.getLog().error("IGC:prepare:Algun valor null, Actual :"
                        +this.getIdContenidorActual());
            if (this.contenidor!=null)
                this.getLog().error("IGC:prepare:Algun valor null, contenidor :"
                        +contenidor.toString());
        }

    }

 
    public Long getIdContenidorActual() {
        return idContenidorActual;
    }

    public void setIdContenidorActual(Long idContenidorActual) {
        this.idContenidorActual = idContenidorActual;
    }

/* Emili:31-12-2011
    public Contenidor getContenidor() {
        return contenidor;
    }

    public void setContenidor(Contenidor contenidor) {
        this.contenidor = contenidor;
    }
*/
  
    public int getContenidorsPerPagina() {
        return this.contenidorsPerPagina; //Config.CONTENIDOR_PAGE;
    }

    public void setContenidorsPerPagina(int contenidorsPerPagina) {
        this.contenidorsPerPagina = contenidorsPerPagina;
    }

    public int getItemsPerPagina() {
        return itemsPerPagina;
    }

    public void setItemsPerPagina(int itemsPerPagina) {
        this.itemsPerPagina = itemsPerPagina;
    }




    public int getPos() {
        return pos;
    }

    //Es filtra ja que és un valor que es pot passar com a paràmetre a l'URL
    public void setPos(int pos) {
        InjeccioCodi filtre=new InjeccioCodi();
        this.pos = Integer.parseInt(filtre.netejar(pos));
    }

    public void setNContenidors(int _nContenidors) {
        this.nContenidors = _nContenidors;
    }

 
    public void setNItems(int _nItems) {
        this.nItems = _nItems;
    }


    public void setLlistaCon(List<ContenidorLlistat> _llistaCon) {
        this.llistaCon = _llistaCon;
    }


    public List<ContenidorLlistat> getLlistaCon() {

     //13 10:23   if (this.llistaCon.equals(null))
      //13 20:52      llistaCon=this.omplirLlistaContenidors(this.getPos(),
       //                 (this.getPos()+this.getContenidorsPerPagina()));
        
        return llistaCon;
    }

    public List<ItemLlistat> getLlistaIt() {
      //13 10:23   if (this.llistaIt.equals(null))
            //23 17:27 llistaIt=this.omplirLlistaItems(this.getContenidor(),this.getPos(),
                       //     (this.getPos()+this.getItemsPerPagina()));

        return llistaIt;
    }

    public void setLlistaIt(List<ItemLlistat> llistaIt) {
        this.llistaIt = llistaIt;
    }



    public int getNContenidors() {
       //13 10:23 if (this.nContenidors==Config.valorNullInt)
       //13 11:27 this.setNContenidors(this.quants(Contenidor.class));
        return this.nContenidors;
    }

    public int getNItems() {
      //13 10:23 if (this.nItems==Config.valorNullInt)
           //13 11:27 if (this.getIdContenidorActual().equals(Config.valorNull))
           //13: 11:27         this.setNItems(this.quants(Item.class));
            //13 11:27 else    this.setNItems(this.getContenidor().getItems().size());
        return this.nItems;
    }


     /**
     *  Crea una instància cap al Gestor de Contenidors si no existeix encara
     */

    private void openGestor(){

        //Emili:31-12-2011: if (this.gcI==null)
        //    gu=new GestorUsuaris();
        gcI=GestorContenidors.getInstance();
    }

    private void closeGestor(){
        /*Emili:31-12_2011: if (this.gcI!=null){
            gcI.tancar();
            gcI=null;}
         * */
         try{
            gcI.tancar();
            gcI=null;
        }catch(HibernateException e){
            getLog().error("Hi ha hagut un error realitzant el tancament del Gestor ", e.getLocalizedMessage());
        }catch (NullPointerException e){
            this.getLog().info("Gestor de contenidors ja tancat");
        }
    }


    //En tancar la classe es tanquen les connexions creades
 /*Emili31-12-2011:   @Override
    protected void finalize() throws Throwable {

        try {
            this.closeGestor();
        } catch(Exception e) {
            this.getLog().error("Error tancant la classe Gestora");
        }finally {
            super.finalize();
        }
    }
*/
    private List<ContenidorLlistat> omplirLlistaContenidors(int ini, int fi){

        Iterator <Contenidor> ll=null;
        List<ContenidorLlistat> llistaC = new ArrayList<ContenidorLlistat>();
        openGestor();
        try {
            //Comprovació de rangs
            if (ini < 0) ini=0;
            //ll=gc.llistatContenidors(ini, fi);
            ll=gcI.llistat(ini, fi);
            while (ll.hasNext()){
                Contenidor c=(Contenidor)ll.next();
                //this.llistaCon.add(new ContenidorLlistat(c.getId(),c.getNom(),c.getDataPub(),c.getItems().size()));
                llistaC.add(new ContenidorLlistat(c.getId(),c.getNom(),c.getDatapub(),c.getItems().size()));
            }
        }catch (HibernateException ex) {
                this.getLog().error("no s'ha pogut obtenir el nombre de contenidors",ex.getLocalizedMessage());
            
        }catch (LlistatDAOException ex) {
                this.getLog().error("Error: Llistat. ",ex.getLocalizedMessage());
        }catch (IndexOutOfBoundsException ex) {
                this.getLog().error("Error: La llista de contenidors es troba fora de rang ",ex.getMessage());
        }
        ll=null;
        return llistaC;
    }

    private List<ItemLlistat> omplirLlistaItems(Contenidor c,int ini, int fi){

        Iterator <Item> ll=null;
        List<ItemLlistat> llistaI = new ArrayList<ItemLlistat>();

        //Emili:30-12-2011:int punter=0;
        try {
            //Comprovació de rangs 
            if (ini < 0) ini=0;
            if (fi +1>= this.getNItems()) fi=this.getNItems();

            ll=c.getItems().subList(ini, fi).iterator();
            while (ll.hasNext()){
                Item i=(Item)ll.next();
                //Es delimita la llista per la paginació
                //if (punter >=ini && punter <=fi)
                llistaI.add(new ItemLlistat(i.getId(),i.getNom(),i.getDatapub()
                        ,i.getAutor(),i.getVisites(),i.getArxiu().getTipus()
                        ,c.getNom(), i.getPrivat()) );
                //punter++;
            }
        }catch (HibernateException ex) {
                this.getLog().error("IGC:omplirLlistaItems:no s'ha pogut obtenir els "
                        +"d'Ítems",ex.getLocalizedMessage());

        }catch (NullPointerException ex) {
                this.getLog().error("IGC:omplirLlistaItems:Llistat d'Ítems. Alguns "
                   +"dels valors necessaris és null ",ex.getLocalizedMessage());
        }catch (IndexOutOfBoundsException ex) {
                this.getLog().error("IGC:omplirLlistaItems:La llista d'ítems es "
                        +"troba fora de rang ",ex.getLocalizedMessage());
        }//finally{
             //   gc.tancar();
            //}

        ll=null;

        //}
        return llistaI;
    }


 /**
 *
 * @return nombre d'elements  Contenidors (Classe)
 */
    //TODO:15-12-11:Emili: Caldrà fer servir la interfície InterfaceiInGestor
    private int quants(Class obj){
        int num=Config.valorNullInt;
        String classeNom=obj.getSimpleName();
        openGestor();

        try {
            //5 GestorContenidors gc = new GestorContenidors();
            if ( classeNom.equals(Contenidor.class.getSimpleName())){
                //GestorContenidors gestor = new GestorContenidors();
                num = gcI.numContenidors();
                //gestor.tancar();
            }else if (classeNom.equals(Item.class.getSimpleName())){
                GestorItems gestor = GestorItems.getInstance();
                num = new Integer(gestor.numItems());
                gestor.tancar();
            }
            //5 gc.tancar();
          } catch (HibernateException ex) {
            String[] llista ={obj.getSimpleName(),ex.getLocalizedMessage()};
            this.getLog().error("no s'ha pogut obtenir el nombre d'elements ,Classe :{}. {}",llista);
            //num=0;
        }catch(BuitException e){
            this.getLog().error("llista buida. Classe :"+obj.getSimpleName(),e.getLocalizedMessage());
            //num=0;
        }

        return num;

    }

    public String editar(){
        return this.afegir();//emili:31-12-2011:return ActionSupport.INPUT;
    }

    public String afegir(){
           this.openGestor();
        return ActionSupport.INPUT;
    }

 
    public String llistat() {
        try{
            this.setNContenidors(this.quants(Contenidor.class));
            this.setNItems(this.quants(Item.class));
            if (!comprovarLimits(this.getPos(),0,this.getNContenidors())) {
                this.addActionError("Límits de posició fora de rang");
                return ActionSupport.ERROR;
            }
            //this.omplirLlistaContenidors( this.getPos(), this.getPos()+Config.CONTENIDOR_PAGE-1);
            //this.getLog().info("Pos: "+this.getPos());
            //this.getLog().info("nContenidors: "+this.getNContenidors());

          //13 10:23  if (this.getLlistaCon().isEmpty())
                this.setLlistaCon(
                        this.omplirLlistaContenidors( this.getPos(),
                            this.getPos()+this.getContenidorsPerPagina()));
        }catch(NullPointerException e){
            this.getLog().error("Error obtenint la llista de contenidors. {}",e.getLocalizedMessage());
        }

        return ActionSupport.SUCCESS;
    }

    

    public String consulta(){
        Contenidor co=null;
        openGestor();
        try {

            //Obtenir dades del contenidor
            co=gcI.llegirContenidor(idContenidorActual);

            //S'indica el número d'ítems del contenidor per fer la paginació
            this.setNItems(co.getItems().size());

            //13 10:23 if (this.getLlistaIt().isEmpty())
            this.setLlistaIt( this.omplirLlistaItems(co,this.getPos(),
                    (this.getPos()+this.getItemsPerPagina())));

        }catch(NullPointerException e){
            this.getLog().error("Error obtenint la llista d`Ítems. {}",e.getLocalizedMessage());
        }catch (LlegirDAOException ex) {
                this.getLog().error("Error obtenint la llista d'ítems del contenidor. {}",ex.getLocalizedMessage());
            }
        return ActionSupport.SUCCESS;
    }


    public String editarForm(){
        String stat=Config.CORRECTE;

        try {

            this.openGestor();
            // tenim una insercio o modificacio ?
             
            //this.getLog().info("id: contenidor:"+getModel().getId());
            if (this.getModel().getId()!=Config.valorNull){

                //MODIFICACIÓ
                 addActionMessage("Modificació Contenidor :"
                         +this.getModel().toString());

                Contenidor con=gcI.modificar(contenidor);
                addActionMessage("contenidor modificat, id: "
                        +this.getIdContenidorActual());

            }else {

                //INSERCIÓ
                Long idCont=Config.valorNull;
                idCont=gcI.afegir(contenidor);
                addActionMessage("Contenidor afegir, id: " +idCont.toString());
            }

            this.closeGestor();
            //Actualitzem les dades
//          this.llistat();

            stat=Config.CORRECTE;
        }catch (AfegirDAOException ex) {
                this.getLog().error("La base de dades informa d'un error en l'entrada del contenidor. ",ex.getLocalizedMessage() );
                stat=ActionSupport.ERROR;

        }catch (ModDAOException ex) {
                this.getLog().error("Hi ha hagut un error realitzant la modificació del contenidor ", ex.getLocalizedMessage());
                stat=ActionSupport.ERROR;

        }catch (NullPointerException e){
                this.getLog().error("Valor null trobat ", e.getMessage());
                stat=ActionSupport.ERROR;
        }
        return stat;
    }

    public String eliminar(){
        String stat="llistatContenidors";
        openGestor();

        if (this.getIdContenidorActual()!=null){
            stat=Config.CORRECTE;
            try{
                //5 GestorContenidors gc = new GestorContenidors();

                Contenidor c=gcI.llegirContenidor(this.getIdContenidorActual());
                this.getLog().info("IdContenidorActual: "+this.getIdContenidorActual());
                this.getLog().info("cotenidor: "+c);
                if (c != null){
                    gcI.eliminarContenidor(this.contenidor);
                    //5 gc.tancar();
                    addActionMessage("Contenidor eliminat : " +this.contenidor.getNom());
                    this.contenidor=null;
                }else  throw new BuitException("Contenidor no trobat");

            }catch (EliDAOException e){
                this.getLog().error("S'ha produit un error eliminant el contenidor",e.getMessage());
                this.addActionError("Contenidor no eliminat, id:"+this.getIdContenidorActual());
                this.addActionError(e.getMessage());
                stat=ActionSupport.ERROR;

            }catch (LlegirDAOException e){
                this.getLog().error("Un dels valors llegits. Id no eliminat: "+this.getIdContenidorActual(), e.getMessage());
                this.addActionError("Contenidor no eliminat, id:"+this.getIdContenidorActual());
                this.addActionError(e.getMessage());
                stat=ActionSupport.ERROR;

            }catch (IllegalArgumentException e){
                this.getLog().error("El paràmetre indicat no és correcte: "+this.getIdContenidorActual(), e.getMessage());
                this.addActionError("Contenidor no eliminat, id:"+this.getIdContenidorActual());
                this.addActionError(e.getMessage());
                stat=ActionSupport.ERROR;

            }catch (BuitException e){
               this.getLog().error("S'ha produit un error eliminant el contenidor:",e.getMessage());
                this.addActionError("Contenidor no eliminat, id:"+this.getIdContenidorActual());
                this.addActionError(e.getMessage());
                stat=ActionSupport.ERROR;
            }catch (NullPointerException e){
                this.getLog().error("Valor null trobat ", e.getLocalizedMessage());
                stat=ActionSupport.ERROR;
            }
            
        }

       //1 gc.tancar();
        return stat;
    }


 
 /**
  *
  * MAIN
  */
 /*   public static void main(String[] args){
        //TODO : proves
        IGestorContenidors ip=new IGestorContenidors();


        Contenidor c;
        try {
            c = ip.gc.llegirContenidor(1000L);
            c.setNom(c.getNom().concat("_nou"));
            ip.gc.modificarContenidor(c);
        } catch (LlegirDAOException ex) {
            Logger.getLogger(IGestorContenidors.class.getName()).log(Level.SEVERE, null, ex);
        }catch (ModDAOException ex) {
                Logger.getLogger(IGestorContenidors.class.getName()).log(Level.SEVERE, null, ex);
            }


        Eines.escriu("nombre de contenidors: "+ip.getNContenidors());
        //Eines.escriu(ip.llistaUltimsItems.iterator().next().getNom());
        //Eines.escriu(ip.llistaContenidors.iterator().next().getNom());

       
       ip.closeGestor();
        
    }


*/
}

